
package com.zdzx.controller.web;

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.Calendar;
import java.util.List;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.github.bingoohuang.patchca.color.SingleColorFactory;
import com.github.bingoohuang.patchca.custom.ConfigurableCaptchaService;
import com.github.bingoohuang.patchca.filter.predefined.CurvesRippleFilterFactory;
import com.github.bingoohuang.patchca.font.RandomFontFactory;
import com.github.bingoohuang.patchca.service.Captcha;
import com.github.bingoohuang.patchca.word.RandomWordFactory;
import com.zdzx.base.common.util.RedisUtil;
import com.zdzx.common.result.Result;
import com.zdzx.common.result.ResultCode;
import com.zdzx.common.result.ResultUtil;
import com.zdzx.common.util.Md5Util;
import com.zdzx.mapper.SystemConfigMapper;
import com.zdzx.mapper.UserMapper;
import com.zdzx.model.service.base.param.EditUser;
import com.zdzx.model.service.base.param.ForgotPassword;
import com.zdzx.model.service.base.param.LoginInfo;
import com.zdzx.model.service.base.param.RegisterUser;
import com.zdzx.model.service.base.param.SendMobile;
import com.zdzx.model.service.base.result.UserInfo;
import com.zdzx.model.service.base.vo.SystemConfig;
import com.zdzx.model.service.base.vo.User;
import com.zdzx.service.UserService;
import com.zdzx.utils.MobileMessage;
import com.zdzx.utils.MobileUtil;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

@Api(tags = "webindex")
@RestController()
@RequestMapping("/web")
public class WebIndexController {

	
	@Autowired
	private RedisUtil redisUtil;
	@Autowired
	private UserService userService;
	@Autowired
	private UserMapper userMapper;
	@Autowired
	private SystemConfigMapper configMapper;

	@ApiOperation(value = "刷新token", notes = "")
	@GetMapping("/refToken")
	public Result<String> refToken(HttpServletRequest request) {
		String token=request.getHeader("Authorization");
		return userService.refToken(token);
	}

	@ApiOperation(value = "登录", notes = "")
	@PostMapping("/login")
	public Result<UserInfo> login(@RequestBody LoginInfo loginInfo,HttpServletRequest request) {
		loginInfo.setFrom("WEB");
		return  userService.login(loginInfo,request);
	}

	@ApiOperation(value = "登出", notes = "")
	@GetMapping("/logout")
	public Result<String> logut(HttpServletRequest request) {
		String token=request.getHeader("Authorization");
		return userService.logout(token);
	}

	@ApiOperation(value = "注册", notes = "")
	@PostMapping("/register")
	public Result<String> register(@RequestBody RegisterUser entity) {
		Result<String> result = null;
		String vcode = (String) redisUtil.get("mobileCode:"+entity.getAccount());
		if (StringUtils.isEmpty(vcode) || !vcode.equals(entity.getVcode())) {
			result = ResultUtil.data(ResultCode.MOBILE_CODE_ERROR.getCode(), "验证码不正确", null);
		} else if (StringUtils.isEmpty(entity.getAccount())||entity.getAccount().length()>11) {
			result = ResultUtil.data(ResultCode.RESULT_ERROR.getCode(), "手机号长度不正确", null);
		} else if (entity.getAccount().length() != 11) {
			result = ResultUtil.data(ResultCode.RESULT_ERROR.getCode(), "手机号格式不正确", null);
		}else if (StringUtils.isEmpty(entity.getPassword())||entity.getPassword().length()>32) {
			result = ResultUtil.data(ResultCode.RESULT_ERROR.getCode(), "密码长度不能正确", null);
		} /*else if (StringUtils.isEmpty(entity.getRealName())||entity.getRealName().length()>10) {
			result = ResultUtil.data(ResultCode.RESULT_ERROR.getCode(), "姓名长度不正确", null);
		}else if (StringUtils.isEmpty(entity.getIdCard())||entity.getIdCard().length()>19) {
			result = ResultUtil.data(ResultCode.RESULT_ERROR.getCode(), "身份证长度不正确", null);
		}*/else if (!entity.getPassword().equals(entity.getConfirmPassword())) {
			result = ResultUtil.data(ResultCode.RESULT_ERROR.getCode(), "两次密码不一致", null);
		} else {
			QueryWrapper<User> queryWrapper=new QueryWrapper<User>();
			queryWrapper.select("id");
			queryWrapper.eq("account", entity.getAccount());
			List<User> list = userMapper.selectList(queryWrapper);
			if(list!=null&&list.size()>0) {
				return ResultUtil.data(ResultCode.MOBILE_EXIT.getCode(),ResultCode.MOBILE_EXIT.getMes(), null);
			}
			
			EditUser user1 = new EditUser();
			BeanUtils.copyProperties(entity, user1);
			User user=new User();
			BeanUtils.copyProperties(user1, user);
			if(!StringUtils.isEmpty(user.getPassword()))
				user.setPassword(Md5Util.hash(user.getPassword()));
			user.setCreateTime(LocalDateTime.now());
			int rows = userMapper.insert(user);
			return ResultUtil.data(rows>0?ResultCode.RESULT_SUCCESS.getCode():ResultCode.RESULT_ERROR.getCode(), null, null);
		}
		return result;

	}

	@ApiOperation(value = "图片验证码", notes = "")
	@GetMapping("/imageCode")
	public void vCode(@RequestParam("r")String r,HttpServletRequest request, HttpServletResponse response) {
		String requestId = r;//request.getHeader("x-request-id");
		
		try {
			BufferedImage image = imageCode(requestId, request, response);
			ImageIO.write(image, "JPG", response.getOutputStream());
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	@ApiOperation(value = "发送验证码", notes = "")
	@PostMapping("/sendMobile")
	public Result<String> sendMobile(@RequestBody SendMobile sendMobile,HttpServletRequest request) {
		//String requestId = request.getHeader("x-request-id");
		String imageCode = (String)redisUtil.get(sendMobile.getR());
		if(StringUtils.isEmpty(imageCode)||!imageCode.equals(sendMobile.getImageCode())) {
			return ResultUtil.data(ResultCode.MOBILE_CODE_ERROR.getCode(), "验证码不正确", null);
		}
		Random ran = new Random();
		String code = "";
		for (int i = 0; i < 6; i++) {
			code += ran.nextInt(10);
		}
		redisUtil.del(sendMobile.getR());
		Result<MobileMessage> sendCode = MobileUtil.sendCode(sendMobile.getMobile(),code);//ResultUtil.data(ResultCode.RESULT_SUCCESS.getCode(), null,null);
				//MobileUtil.sendCode(sendMobile.getMobile(),code);
				//MobileUtil.sendCode(sendMobile.getMobile(),code);
		if(ResultCode.RESULT_SUCCESS.getCode().equals(sendCode.getCode())) {
			redisUtil.set("mobileCode:"+sendMobile.getMobile() , code, 1000 * 60 * 5);
			return ResultUtil.data(ResultCode.RESULT_SUCCESS.getCode(), null, code);
		}
		return ResultUtil.data(ResultCode.RESULT_ERROR.getCode(), "验证码发送失败", code);
	}
	
	@ApiOperation(value = "找回密码", notes = "")
	@PutMapping("/forgotPassword")
	public Result<String> forgotPassword(@RequestBody ForgotPassword forgotPassword ,HttpServletRequest request) {
		
		String code = (String)redisUtil.get("mobileCode:"+forgotPassword.getMobile());
		if (StringUtils.isEmpty(code)||!code.equals(forgotPassword.getCode())) {
			return ResultUtil.data(ResultCode.MOBILE_CODE_ERROR.getCode(),"验证码不正确", code);
		}else if(!forgotPassword.getAgainPassword().equals(forgotPassword.getPassword())) {
			return ResultUtil.data(ResultCode.AGAIN_PASSWORD.getCode(),"两次密码不正确", code);
		}else {
			User entity=new User();
			entity.setPassword(Md5Util.hash(forgotPassword.getPassword()));
			UpdateWrapper<User> updateWrapper=new UpdateWrapper<User>();
			updateWrapper.eq("account", forgotPassword.getMobile());
			int update = userMapper.update(entity, updateWrapper);
			return ResultUtil.data(update>0?ResultCode.RESULT_SUCCESS.getCode():ResultCode.RESULT_ERROR.getCode(), null, null);
		}
		
	}
	
	/**
	 * 图片验证码
	 * 
	 * @param request
	 * @param response
	 * @throws IOException
	 */
	public BufferedImage imageCode(String authId, HttpServletRequest request, HttpServletResponse response)
			throws IOException {

		response.setHeader("Pragma", "No-cache");
		response.setHeader("Cache-Control", "no-cache");
		response.setDateHeader("Expires", 0);

		int width = 90, height = 40;

		// 开源验证码patchca
		ConfigurableCaptchaService cs = new ConfigurableCaptchaService();
		cs.setFilterFactory(new CurvesRippleFilterFactory(cs.getColorFactory()));
		cs.setColorFactory(new SingleColorFactory());
		cs.setWidth(width);
		cs.setHeight(height);

		// 随机字体生成器
		RandomFontFactory fontFactory = new RandomFontFactory();
		fontFactory.setMaxSize(35);
		fontFactory.setMinSize(31);
		cs.setFontFactory(fontFactory);

		// 随机字符生成器,去除掉容易混淆的字母和数字,如o和0等
		RandomWordFactory wordFactory = new RandomWordFactory();
		wordFactory.setCharacters("abcdefghkmnpqstwxy3456789");
		wordFactory.setMaxLength(5);
		wordFactory.setMinLength(4);
		cs.setWordFactory(wordFactory);
		fontFactory.setWordFactory(wordFactory);

		Captcha captcha = cs.getCaptcha();
		// 取得验证码字符串放入Session
		String validationCode = captcha.getChallenge();

		// 取得验证码图片并输出
		BufferedImage image = captcha.getImage();
		boolean set = redisUtil.set(authId, validationCode,60*2);
		System.out.println(set);
		return image;
	}
	
	

	@ApiOperation(value = "网站访问量", notes = "")
	@GetMapping("/pv")
	public Result<String> pv(HttpServletRequest request){
		String ip = "";
		if(request.getHeader("x-forwarded-for") == null) {
			ip = request.getRemoteAddr();
		}else{
			ip = request.getHeader("x-forwarded-for");
		}
		SystemConfig selectById = configMapper.selectById("2");
		String views = (String)redisUtil.get("PV:"+ip);
		if(StringUtils.isEmpty(views)) {
			String value = selectById.getValue();
			System.out.println(value);
			selectById.setValue((Integer.parseInt(selectById.getValue())+1)+"");
			configMapper.updateById(selectById);
			redisUtil.set("PV:"+ip,"0",getMiao());
		}
		return ResultUtil.data(ResultCode.RESULT_SUCCESS.getCode(), "", selectById.getValue());
	}
	public static int getMiao(){
		//long milliSecondsLeftToday = 86400000 - DateUtils.getFragmentInMilliseconds(Calendar.getInstance(), Calendar.DATE);
        long secondsLeftToday = 86400 - DateUtils.getFragmentInSeconds(Calendar.getInstance(), Calendar.DATE);
        return (int)secondsLeftToday;
	}
}
